﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.ObjectModel;
using DataFactory;
using Microsoft.Office.Interop.Excel;
using MVVM.Core;
using ObjectModel.Excel;
using System.Text.RegularExpressions;

namespace ViewModels
{
    public class LinkedRangesViewModel : ViewModelBase
    {
        static Application mApp = Globals.Application;
        LinkedRangesCollection mLinkedRanges = new LinkedRangesCollection(mApp.ActiveWorkbook);
        bool mIsEnabled = true;
        ObjectModel.Excel.WorkbookEvents mEvents;

		public LinkedRangesViewModel() {
			Restore();

            mEvents = new ObjectModel.Excel.WorkbookEvents(mApp.ActiveWorkbook);
            mEvents.AfterSave += WorkbookAfterSave;
			mApp.WorkbookOpen += WorkbookChange;
		}

        public Application Application
        {
            get { return mApp; }
        }

        public bool IsEnabled
        {
            get { return mIsEnabled; }
            set
            {
                mIsEnabled = value;
                LinkedRanges.IsSelectionLocked = !value;
                OnPropertyChanged("IsEnabled");
            }
        }

		void WorkbookChange(Workbook Wb)
		{
			mLinkedRanges.Clear();
			mLinkedRanges.Workbook = Wb;
			Restore();
		}

        public LinkedRangesCollection LinkedRanges
        {
            get { return mLinkedRanges; }
        }

        public void AddLinkedRange()
        {
            Range range = mApp.Selection as Range;
            
            AddLinkedRange(range);
        }
        
        public void AddLinkedRange(Range range) {
            LinkedRange linkedRange = new LinkedRange(range);

            mLinkedRanges.Add(linkedRange);
        }

        public void RemoveLinkedRangeAt(int index)
        {
            if (index != -1)
                LinkedRanges.RemoveAt(index);
        }

        void WorkbookAfterSave(object sender, EventArgs e)
        {
            Save();
        }

        public void Save()
        {
            // Serialize linked ranges.
			foreach(var linkedRange in LinkedRanges)
				LinkedRangeSerializer.SerializeOne(mApp.ActiveWorkbook, linkedRange);
        }

        public void Restore()
        {
            // Deserialize linked ranges.
        	foreach(var linkedRange in LinkedRangeSerializer.DeSerializeAll<LinkedRange>(mApp.ActiveWorkbook, "LinkedRange")) {
        		LinkedRanges.Add(linkedRange);
        	}
        }

        public void UpdateSelected()
        {
            LinkedRanges.SelectedItem.UpdateValues();

            if (LinkedRanges.SelectedItem.SourceRange.WorkbookOpenedProgrammatically)
                LinkedRanges.SelectedItem.SourceRange.Workbook.Close(false);
        }

        public void UpdateAll()
        {
            foreach (LinkedRange range in mLinkedRanges)
                range.UpdateValues();

            CloseSourceWorkbooks();
        }

        public void SetSourceRange(Range range) {

        	LinkedRanges.SelectedItem.SourceRange.Range = range; 
			LinkedRanges.SelectedItem.UpdateValues();
		}

        public void CloseSourceWorkbooks()
        {
            IEnumerable<Workbook> workbooksToClose = from r in LinkedRanges
                                                     where r.SourceRange.WorkbookOpenedProgrammatically
                                                     select r.SourceRange.Workbook;

            // Close the workbooks.
            foreach (Workbook wb in workbooksToClose)
                wb.Close(false);
        }

        public void SetSourceWorkbook() {
        	dynamic result = mApp.GetOpenFilename();
        	
			if(result is string)
        		LinkedRanges.SelectedItem.SourceRange.WorkbookFullName = (string)result;
        }

    	public void AddCondition()
        {
            OfflineSourceRange range = new OfflineSourceRange() { Workbook = LinkedRanges.SelectedItem.SourceRange.Workbook };
            ValueCondition condition = new ValueCondition() { ConditionalRange = range };

            LinkedRanges.SelectedItem.SourceRange.Conditions.Add(condition);
        }

        public void RemoveCondition(ValueCondition condition)
        {
            LinkedRanges.SelectedItem.SourceRange.Conditions.Remove(condition);
        }

		public void AddColLookupStep(LookUpStep step) {
			
		}

		public void AddRowLookupStep(LookUpStep step) {
			
		}
    }
}
